#!/usr/bin/python
# -*- coding: UTF-8 -*-
import queue
import shutil

import PyQt5
from PyQt5.QtWidgets import QApplication, QWidget, QFormLayout, QLineEdit, QLabel
from concurrent.futures import ThreadPoolExecutor
import random
import sys
import cv2
import os
import numpy as np
import json
import threading
import time
from collections import Counter

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import QPalette, QBrush, QPixmap
from PyQt5.QtCore import QTimer
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

from ClientUi.tools.gui_utils import SettingCheckBox, showimg
#import defconfig
#import get_config
from get_config import *
#from common.utils import *
from ClientUi.controls.pyqt_imshow import *
#from sengo_common.test_peifang_gui import *
from PIL import Image, ImageDraw, ImageFont

nowdate = get_date_stamp()
stat_data = {}
stat_fn = f'{out_img_p}/stat_{nowdate}.json'
if os.path.exists(stat_fn):
    try:
        stat_data = json.load(open(stat_fn, 'r'))
    except Exception as e:
        stat_data = {}
        pass


def draw_text_cn(img, text, left, top, textcolor=(0, 0, 255), textsize=2):
    if isinstance(img, np.ndarray):
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(img)
    textcolor = (textcolor[2], textcolor[1], textcolor[0])
    fontstyle = ImageFont.truetype(
        "font/simsun.ttc", textsize, encoding='utf-8')
    draw.text((left, top), text, textcolor, font=fontstyle)
    return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)


def draw_out1(im1, ccc, end):
    color_chengse = (0, 165, 255)
    color_green_shen = (0, 165, 0)
    colors = [(0, 255, 0), (0, 0, 255)]
    texts = ['OK', 'NG']
    minilabs = 'guan xiantou xiantou_bai xiantou_bai2 xiantou2 xiantou3'.split()
    for i in range(9):
        minilabs += f'xiantou_bai{i} xiantou{i}'.split()
    for xx in ccc:
        r, c, conf = xx[:3]
        s = 2
        xxs = [x for x in xx if isinstance(x, str)]
        linew = max(2, int(rect_height(r)/100))
        text = c
        if conf>0:
            text = f'{c} {conf:.1f}'
            
        if 'not_' in c or c in 'handian'.split():
            continue

        end1 = 0
        seg = []
        if 'NG' in xxs:
            end1 = 1
        color = colors[end1]
        if 0:
            color = colors[0]
    
        if c in 'louhan guanao guoshao louhan zouxianng'.split():
            color = colors[1]

            
        if len(xx)>3:
            if 'NG' in xxs:
                color = colors[1]
            if isinstance(xx[3], str) and xx[3] in ['paichu']:
                color = color_chengse
                
        color = colors[end]

        if c in minilabs:
            linew = 3
            s = 1
        if c in ['jianxi']:
            draw_line(im1, r, color, linew)
            text = f'{c} {conf:.1f}'
        else:
            if len(xx)>3 and isinstance(xx[3], np.ndarray):
                seg = xx[3].astype(np.int32)
                cv2.polylines(im1, [seg], True, color, linew)
            else:
                drawrect(im1, r, color, linew)
        if c not in minilabs or 1:
            color = (np.array(color)*0.8).astype(np.int32).tolist()
            cv2.putText(im1, text, (int(r[0]), int(r[1])), cv2.FONT_HERSHEY_SIMPLEX, s, color, s)
        #draw_text_cn(im1, text, r[:2], (0, 0, 255))
    if 1:
        text = (0, 0, 255) if end else (0, 255, 0)
        text = texts[end]
        cv2.putText(im1, f'{text}', (100, 250), cv2.FONT_HERSHEY_COMPLEX_SMALL, 16.2, colors[end], 20)
    return im1

# from test_serial import write_bin

class BoundThreadPoolExecutor(ThreadPoolExecutor):
    # 对ThreadPoolExecutor 进行重写，给队列设置边界
    def __init__(self, qsize: int = None, *args, **kwargs):
        super(BoundThreadPoolExecutor, self).__init__(*args, **kwargs)
        self._work_queue = queue.Queue(qsize)


pool = BoundThreadPoolExecutor(qsize=8, max_workers=8)

hv_layout = [QHBoxLayout, QVBoxLayout]


# detect_a0 = codescanner_a1

def lay2w(button_color_hbox_layout):
    button_color = QWidget()
    button_color.setLayout(button_color_hbox_layout)
    return button_color


def layout_it(obj, level):
    if isinstance(obj, list):
        out = hv_layout[level % 2]()
        for x in obj:
            a = layout_it(x, level + 1)
            if 'Layout' in str(type(a)):
                out.addLayout(a)
            else:
                out.addWidget(a)

        return out

    return obj


def layout_ita(obj, level, alignment=Qt.AlignCenter):
    if isinstance(obj, list):
        out = hv_layout[level % 2]()
        for x in obj:
            a = layout_it(x, level + 1)
            if 'Layout' in str(type(a)):
                out.addLayout(a)
            else:
                out.addWidget(a, alignment=alignment)

        return out

    return obj


def layout_itf1(obj, level, factor):
    if isinstance(obj, list):
        f = 0
        factor = factor if isinstance(factor, list) else [
            (factor + len(obj) - 1) // len(obj) for j in obj]
        out = hv_layout[level % 2]()
        for i in range(len(obj)):
            x = obj[i]
            a, f1 = layout_itf1(x, level + 1, factor[i])
            if 'Layout' in str(type(a)):
                out.addLayout(a)
            else:
                out.addWidget(a)

            if f1 > 0:
                out.setStretchFactor(a, f1)

            f += f1

        return out, f

    return obj, factor


def layout_itf(obj, level, factor):
    return layout_itf1(obj, level, factor)[0]


# NewWidget是随便起的名字，QWidget是要重写的，继承给NewWidget
def make_grid(labs):
    grid = QGridLayout()
    dd = {}
    for i in range(len(labs)):
        la_cameraid = QLabel(labs[i])
        lb_cameraid = QLabel()
        la_cameraid.setBuddy(lb_cameraid)
        grid.addWidget(la_cameraid, i, 0)
        grid.addWidget(lb_cameraid, i, 1)
        lb_cameraid.setMinimumWidth(100)
        dd[labs[i]] = lb_cameraid

    return grid, dd


def make_grid2(labs):
    grid = QGridLayout()
    dd = {}
    for i in range(len(labs)):
        for j in range(len(labs[0])):
            la_cameraid = QLabel(labs[i][j])
            lb_cameraid = QLabel()
            la_cameraid.setBuddy(lb_cameraid)
            grid.addWidget(la_cameraid, i, j * 2 + 0)
            grid.addWidget(lb_cameraid, i, j * 2 + 1)
            lb_cameraid.setMinimumWidth(100)
            dd[labs[i][j]] = lb_cameraid

    return grid, dd


def make_grid_lay(gg):
    grid = QGridLayout()
    for row in range(len(gg)):
        for col in range(len(gg[row])):
            ctrl = gg[row][col]
            if isinstance(ctrl, str):
                ctrl = QLabel(ctrl)
            grid.addWidget(ctrl, row, col)
    return grid


# from test_baozhu import *


def get_last_cpcode(datas, j = -1):
    cpcode = 'cpcode'
    if j<0:
        j += len(datas)
    for i in range(j, 0, -1):
        cpcode = datas[i][1]['成品码']
        if 'code' not in cpcode and len(cpcode)>2:
            break
    
    return cpcode

class Washer():
    def wash(self):
        print('do some laundry stuff')


class LinkLabel(QLabel):
    clicked = pyqtSignal(str)

    def __init__(self, txt, parent=None):
        super(LinkLabel, self).__init__(parent)
        self.txt = txt
        self.sss = f'''<a style="font-family: 微软雅黑; color: #02A5EE; font-size: 10pt;  text-decoration: none">{txt}</a>'''
        self.aaa = f'''<a style="font-family: 微软雅黑; color: #EEA511; font-size: 10pt;  text-decoration: none">{txt}</a>'''
        self.setText(self.sss)
        self.setOpenExternalLinks(True)
        self.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)

    # 鼠标点击事件
    def mousePressEvent(self, event):
        self.setText(self.aaa)
        self.clicked.emit(self.txt)

    def mouseReleaseEvent(self, event):
        self.setText(self.sss)


class ClickLabel(QLabel):
    clicked = pyqtSignal()

    def __init__(self, txt, parent=None):
        super(ClickLabel, self).__init__(parent)
        self.txt = txt
        self.sss = f'''<a style="font-family: 微软雅黑; color: #AAAAAA; font-size: 10pt;  text-decoration: none">{txt}</a>'''
        self.aaa = f'''<a style="font-family: 微软雅黑; color: #EEEEEE; font-size: 10pt;  text-decoration: none">{txt}</a>'''
        self.setText(self.txt)
        # self.setOpenExternalLinks(True)
        # self.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)

    def setText(self, txt):
        self.txt = txt
        self.sss = f'''<a style="font-family: 微软雅黑; color: #AAAAAA; font-size: 10pt;  text-decoration: none">{txt}</a>'''
        self.aaa = f'''<a style="font-family: 微软雅黑; color: #EEEEEE; font-size: 10pt;  text-decoration: none">{txt}</a>'''
        super().setText(self.txt)

    # 鼠标点击事件
    def mousePressEvent(self, event):
        self.setText(self.aaa)
        self.clicked.emit()

    def mouseReleaseEvent(self, event):
        #self.setText(self.sss)
        pass
    
    def enterEvent1(self, event):
        self.setText(self.aaa)
        pass

    def leaveEvent1(self, event):
        self.setText(self.txt)
        pass

    def focusOut(self, event):
        self.setText(self.txt)
        pass

class DataStatistics(QWidget):
    showSignal_data = pyqtSignal(list)

    def __init__(self, parent=None):  # 初始化 并定义界面
        super(DataStatistics, self).__init__(parent)
        self.setWindowTitle("数据统计")
        self.resize(1300, 900)

        self.setupUi()

        self.btn_clear_data = QtWidgets.QPushButton()
        self.btn_clear_data.setText("数据清零")
        self.btn_clear_data.setFixedWidth(200)

        fromlayout = QFormLayout()
        fromlayout.addRow(self.tableWidget)
        # fromlayout.addRow(self.btn_clear_data)
        self.setLayout(fromlayout)
        self.btn_clear_data.clicked.connect(self.clear_data)
        self.showSignal_data.connect(self.test)
        self.threadrun = True

    def test(self):
        pass

    def setupUi(self):
        self.tableWidget = QtWidgets.QTableWidget()
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows+QAbstractItemView.SelectItems)
        self.tableWidget.setGeometry(QtCore.QRect(90, 70, 480, 260))
        # self.tableWidget.setMinimumSize(QtCore.QSize(480, 0))
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableWidget.setShowGrid(True)
        self.tableWidget.verticalHeader().setHidden(True)
        # self.tableWidget.setGridStyle(QtCore.Qt.DashLine)
        self.tableWidget.setGridStyle(QtCore.Qt.SolidLine)
        self.tableWidget.setObjectName("tableWidget")
        # tongji = get_config.tongji

        ncl = len(tongji)

        self.tableWidget.setRowCount(ncl)

        self.tableWidget.horizontalHeader().setVisible(True)
        self.tableWidget.horizontalHeader().setCascadingSectionResizes(False)
        self.tableWidget.horizontalHeader().setHighlightSections(True)
        self.tableWidget.horizontalHeader().setMinimumSectionSize(40)
        self.tableWidget.verticalHeader().setDefaultSectionSize(30)
        # self.tableWidget.verticalHeader().setStyleSheet("QHeaderView::section { background-color: rgb(123, 33, 201); }")
        # self.tableWidget.setStyleSheet("QTableWidget{ gridline-color: #000; }")

        header = self.tableWidget.horizontalHeader()
        # aa = "日期 机型码 条码 结果".split()
        aa = "序号 日期 成品码 MES条码 结果 人工复判结果".split()
        self.aa = aa
        self.aalen = len(aa)
        aa = aa + camnames
        self.fields = aa
        self.data = []
        self.tableWidget.setColumnCount(len(aa))
        self.tableWidget.setHorizontalHeaderLabels(aa)
        self.tableWidget.setColumnWidth(0, 40)
        self.tableWidget.setColumnWidth(1, 120)
        # header.setStyleSheet("QHeaderView::section { background-color: rgb(123, 33, 201); }")
        # header.setMinimumHeight(40)
        # header.sectionClicked.connect(self.order1)
        # header.setSectionResizeMode(QHeaderView.ResizeToContents)
        # header.setSectionResizeMode(QHeaderView.Stretch)
        # hheader.setStretchLastSection(True)
        # header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        # header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        self.retranslateUi()
        # test_data_01 = ["2021_1_dvsvwsvwsfwfwfwrgwwwg", "ok", "ok", "ok", "ok", "ok", "ng", "ok"]
        # list_test_data = [test_data_01] * 8
        # list_test_data.append(["2021_1_", "ok", "ok", "ok", "ok", "ok", "ng", "ok"])
        return self.tableWidget

    def retranslateUi(self):  # 定义表格内容
        ncl = len(tongji)
        # self.tableWidget.setColumnCount(5)
        # self.tableWidget.setRowCount(ncl)
        _translate = QtCore.QCoreApplication.translate
        __sortingEnabled = self.tableWidget.isSortingEnabled()
        self.tableWidget.setSortingEnabled(False)

        # self.update()
        self.tableWidget.setRowCount(0)
        self.idx_h = 0
        return 0

    def add_data(self, li):
        self.data.append(li)
        pp, ddd, ppp = li[:3]
        row_count = self.tableWidget.rowCount()  # 返回当前行数(尾部)
        if 0:
            self.tableWidget.insertRow(row_count)  # 尾部插入一行
            pos = self.idx_h
        else:
            self.tableWidget.insertRow(0)  # 头部插入一行
            pos = 0
        # self.tableWidget.resizeColumnsToContents()
        for ix, x in enumerate(self.aa):
            data_cc = None
            if x in ['序号']:
                data_cc = str(row_count + 1)

            if '条码' in x:
                x = '条码'

            if x in ddd:
                data_cc = ddd[x]
            # if x
            if data_cc is not None:
                item = QTableWidgetItem(data_cc)
                item.setTextAlignment(Qt.AlignCenter)
                if x in ['结果']:
                    if data_cc == 'OK':
                        # item.setForeground(QColor(0, 255, 0))
                        item.setBackground(QColor(0, 255, 0))
                    if data_cc == 'NG':
                        item.setBackground(QColor(255, 0, 0))
                self.tableWidget.setItem(pos, ix, item)

        for i, data_cc in enumerate(ppp):
            ix = self.aalen + i
            if isinstance(data_cc, list):
                if len(data_cc)>0:
                    data_cc = ','.join(data_cc)
                else:
                    data_cc = 'OK'
            # item = LinkLabel(data_cc)
            item = QTableWidgetItem(data_cc)
            item.setTextAlignment(Qt.AlignCenter)
            if data_cc in 'OK':
                # item.setForeground(QColor(0, 255, 0))
                item.setBackground(QColor(0, 255, 0))
            elif data_cc == '无图':
                item.setBackground(QColor(128, 128, 128))
            else:
                item.setBackground(QColor(255, 0, 0))
            self.tableWidget.setItem(pos, ix, item)

        self.idx_h += 1
        # print('ssssss', self.idx_h)
        return 0

    def exptable(self):
        if len(self.fields) and len(self.data):
            import xlwt  # 引入xlwt模块
            book = xlwt.Workbook()
            sheet = book.add_sheet('sheet1')
            aa = get_time_stamp()
            file_name = QFileDialog.getSaveFileName(
                self, "save file", f"{out_img_p}\\{aa}.xls", "xls files(*.xls)")[0]

            if '.xls' not in file_name:
                return

            for col, field in enumerate(self.fields):
                sheet.write(0, col, field)
            for row, data in enumerate(self.data):

                for col, field in enumerate(data):
                    # format Date  这里13/16/18列是日期数据，所以做了单独的格式化处理

                    sheet.write(row + 1, col, field)

            book.save(file_name)
            # QMessageBox.information(self, '提示', '导出成功', QMessageBox.Yes | QMessageBox.Yes)
        else:
            QMessageBox.information(
                self, '提示', '无数据，请先查询', QMessageBox.Yes | QMessageBox.Yes)

        return 0

    def closeEvent(self, event):
        self.threadrun = False

    def clear_data(self):
        # self.data = []
        # for x in tongji:
        #     tongji[x] = 0
        self.retranslateUi()


def test_DataStatistics():
    app = QApplication(sys.argv)
    # if machecinp() or _MachineCheck() == 0:
    ex = DataStatistics()
    ex.setWindowTitle(u'数据统计')
    ex.setWindowIcon(QIcon('ico.png'))
    ex.show()
    sys.exit(app.exec_())


class Ui_CamPaneld(QtWidgets.QLabel):
    def __init__(self, id, parent=None):
        super(Ui_CamPaneld, self).__init__(parent)
        # 信息显示
        ss = ''
        self.id = id
        self.imgs = {}
        grid, self.dd = make_grid(ss.split())

        self.cic = QtWidgets.QLabel()
        self.cic.setFixedSize(QSize(20, 20))
        # print(camnames[id].split(".")[1])
        tt = camnames[id]
        self.name = QtWidgets.QLabel(tt)
        downico = QApplication.style().standardIcon(51)
        self.down = QtWidgets.QPushButton()
        self.down.setIcon(downico)
        self.down.setFixedSize(QSize(20, 20))
        self.down.setToolTip('保存图片')
        
        confico = QApplication.style().standardIcon(56)
        self.conf = QtWidgets.QPushButton()
        self.conf.setIcon(confico)
        self.conf.setFixedSize(QSize(20, 20))
        self.conf.setToolTip('打开模板目录')
        
        self.isok = QtWidgets.QLabel('OK')
        self.isok.setFixedSize(QSize(32, 32))
        self.isok.setAlignment(Qt.AlignCenter)

        ss = '总数 合格 缺陷'
        gridlay_stat, self.dd_stat = make_grid(ss.split())
        self.grid_stat = QtWidgets.QLabel()
        self.grid_stat.setLayout(gridlay_stat)
        # self.grid_stat.setMaximumWidth(250)
        lay = layout_it([self.cic, self.name, self.down, self.conf], 0)

        # self.grid.setSpacing(10)
        # self.grid.setContentsMargins(10, 10, 10, 10)
        self.setObjectName("CamPaneld")
        #self.lab = QtWidgets.QLabel()
        self.lab = UI_ImageView()
        # lab.setFixedSize(2*641, 2*481)
        self.lab.setAutoFillBackground(False)
        # lay = layout_it([[[lay, grid], self.grid_stat], self.lab], 1)
        lay = layout_it([lay, grid, self.lab], 1)
        # lay.setSpacing(0)
        # lay.setContentsMargins(20, 20, 20, 20)
        # self.lab.setMinimumHeight(300)
        lay.setStretchFactor(self.lab, 2)
        self.setLayout(lay)
        self.setMinimumHeight(200)
        self.sz = self.size()

    def show_img_cam(self, im1):
        sz = self.size()
        if self.sz != sz:
            self.lab.init_trans()
        showimg(self.lab, im1)
        
    def contextMenuEvent(self, event):
        self.useRoRect = True
        menu = QMenu()
        bb = [0, 90, 180, 270]
        rotActions = [menu.addAction(f"旋转{x}度") for x in bb]
        itemactions = []
        if 0:
            menu.addSeparator()
            itemactions = [menu.addAction(x) for x in self.labels]

        action = menu.exec_(self.mapToGlobal(event.pos()))
        point = event.pos()
        # if action == addRectAction:            self.addItem(pos, False)
        # if self.useRoRect and action == addRoRectAction:
        #    self.addItem(pos, True)
        cam_rot = config['cam_rot']
        for i, a in enumerate(rotActions):
            if action == a:
                cam_rot[self.id] = bb[i]
                config_save()


def label_set_ng(lab, b, size=QSize(64, 32)):
    tt = 'NG' if b else 'OK'
    # tt = '不合格' if b else '合格'
    color = '#DD2C2A' if b else '#30AE4D'
    lab.setText(tt)
    k = 32
    # lab.setMaximumHeight(k)
    # lab.setMaximumWidth(k)
    if size is None:
        size = QSize(32, 32)
    lab.setFixedSize(size)
    lab.setAlignment(Qt.AlignCenter)
    lab.setStyleSheet(
        "QLabel{border-radius:3px}"
        "QLabel{background-color:%s}"
        # "QLabel{font:24px bold}"
        % (color)
        # "QLabel{padding:2px 4px}"
    )


def biglabel_set_ng(lab, b):
    tt = '不合格' if b else '合格'
    # tt = '不合格' if b else '合格'
    color = '#DD2C2A' if b else '#30AE4D'
    lab.setText(tt)
    k = 32
    # lab.setMaximumHeight(k)
    # lab.setMaximumWidth(k)
    lab.setFixedSize(QSize(64 * 3, 64))
    lab.setAlignment(Qt.AlignCenter)
    lab.setStyleSheet(
        "QLabel{border-radius:3px}"
        "QLabel{background-color:%s}"
        "QLabel{font:24px bold}"
        % (color)
        # "QLabel{padding:2px 4px}"
    )


def make_cam_grid(self):
    if 0:
        grid, self.dd = make_grid(camnames)
    else:
        camnames2 = []
        for i in range(0, len(camnames), 2):
            camnames2.append([camnames[i], camnames[i + 1]])
        grid, self.dd = make_grid2(camnames2)

    grid.setHorizontalSpacing(40)
    # grid0.setVerticalSpacing(40)

    for x in self.dd:
        label_set_ng(self.dd[x], 0)

    grid = make_pad('结果', grid)
    return grid, self.dd


def check_pass_once(self):
    text, ok = QInputDialog.getText(
        self, '密码输入框', '请输入密码：', QLineEdit.Password)
    if not ok:
        return 0
    if text != config['password']:
        reply = QMessageBox.question(self, '信息', '密码错误',
                                     QMessageBox.Yes)
        # self.loginfo('密码错误')
        return 0
    self.is_logging = 1
    return 1


def create_grid_stat_lay(self):
    wi0 = create_grid_stat(self, 0)
    wi1 = create_grid_stat(self, 1)
    # 在QStackedWidget对象中填充了三个子控件
    stack = QStackedWidget(self)
    stack.addWidget(wi0)
    stack.addWidget(wi1)
    return stack


def check_pass(self, max_times=1):
    for i in range(max_times):
        ret = check_pass_once(self)
        if ret:
            self.update()
            return 1

    return 0


class Ui_StatPaneld(QtWidgets.QLabel):
    def __init__(self, id, parent=None):
        super(Ui_StatPaneld, self).__init__(parent)
        self.is_logging = 0
        self.set_ui()

    def set_ui(self):
        # 信息显示
        ss = camnames
        grid, self.dd = make_cam_grid(self)

        aa = '表示合格 表示不合格'.split()
        bb = [0, 1]
        grid0 = QGridLayout()
        for i in range(2):
            la_cameraid = QLabel()
            label_set_ng(la_cameraid, bb[i], QSize(32 * 3, 32))
            lb_cameraid = QLabel(aa[i])
            la_cameraid.setBuddy(lb_cameraid)
            grid0.addWidget(la_cameraid, i, 0)
            grid0.addWidget(lb_cameraid, i, 1)

        self.biglab = QLabel()
        biglabel_set_ng(self.biglab, 0)
        self.cic = QtWidgets.QLabel()
        self.name = QtWidgets.QLabel(f'停线已经开启')
        downico = QApplication.style().standardIcon(51)
        self.down = QtWidgets.QPushButton()
        self.down.setIcon(downico)
        self.down.setFixedSize(QSize(20, 20))
        self.down.setToolTip('save image')
        s = 'OK'
        # s = '合格'
        self.isok = QtWidgets.QLabel(s)
        self.isok.setFixedSize(QSize(32, 32))
        self.isok.setAlignment(Qt.AlignCenter)

        # self.set_ng(0)

        self.stat_stlay = create_grid_stat_lay(self)
        # wi1 = create_grid_stat(self, 1)
        # self.grid.setSpacing(10)
        # self.grid.setContentsMargins(10, 10, 10, 10)
        self.setObjectName("CamPaneld")
        # self.lab = QtWidgets.QLabel()
        # lab.setFixedSize(2*641, 2*481)
        # self.lab.setAutoFillBackground(False)

        self.chk_running = SettingCheckBox('运行检测', 'running')
        #self.chk_stopline = SettingCheckBox('开启停线', 'stopline')
        self.use_qigang = SettingCheckBox('气缸使用', 'use_qigang')
        self.lockui_btn = QPushButton('界面锁定')
        self.lockui_btn.setMinimumHeight(32)
        self.lockui_btn.setMaximumWidth(232)
        self.lockui_btn.clicked.connect(self.lockui)
        plab = QLabel()
        if 0:
            grid0w = QWidget()
            grid0w.setLayout(grid0)
        lay1 = layout_ita([grid0, grid, self.biglab], 1, alignment=Qt.AlignCenter)
        lay2 = layout_it([plab, self.stat_stlay, self.use_qigang, self.chk_running, self.lockui_btn], 1)
        lay = layout_it([lay1, lay2], 0)
        # lay.setSpacing(0)
        # lay.setContentsMargins(20, 20, 20, 20)
        # self.lab.setMinimumHeight(100)
        # lay.setStretchFactor(self.lab, 2)
        self.setLayout(lay)
        self.setMinimumHeight(150)
        self.setStyleSheet(''  # "font-size:24px;"
                           # "background-color:#2D2F58;"
                           # "background-color:#2D2F58;"
                           # "border-radius:10px;"
                           )
        self.update_ui()

    def lockui(self):
        self.is_logging = 0
        self.stat_stlay.setCurrentIndex(0)

        if len(config['password']) == 0 or check_pass(self):
            # config_save()
            # self.stat_pad.update_ui()
            # self.loginfo('设置成功')
            self.is_logging = 1
            self.stat_stlay.setCurrentIndex(1)
            return 1

    def lockui11(self):
        box = QMessageBox()
        box.addButton('重新输入', QMessageBox.YesRole)
        box.setWindowTitle("错误")
        box.setText("两次密码输入不一致，\n\n请重新输入.....")
        box.exec()

    def update_ui(self):
        ss = '停线未开启'
        color = '#30AE4D'
        hovercolor = '#309E4D'
        if config['stopline']:
            ss = '停线已经开启'
            color = '#DD5C2A'
            hovercolor = '#DD2C2A'
        self.name.setText(ss)
        self.cic.setStyleSheet(  # "QLabel{width:40px;height:40px;}"
            # "QLabel{border-radius:10px}"
            # "QLabel{background-color:%s}" % (color)
            # "QLabel:hover{background-color:%s}" % (hovercolor)
            "QLabel{padding:2px 4px}"
        )
        self.cic.setFixedSize(QSize(20, 20))

    def update_tongji1(self):
        cnt_all = tongji['cnt_all']
        cnt_ng = tongji['cnt_ng']
        cnt_ok = tongji['cnt_ok']

        self.dd_stat['总数'].setText(f'{cnt_all}')
        if cnt_all == 0:
            cnt_all = 1
        # aa = f'{cnt_ng} {cnt_ng * 100 / cnt_all:.1f}%'
        aa = f'{cnt_ok}'
        self.dd_stat['合格数'].setText(aa)
        aa = f'{cnt_ng}'
        self.dd_stat['不合格数'].setText(aa)

        # aa = f'{cnt_ok} {cnt_ok * 100 / cnt_all:.1f}%'
        aa = f'{cnt_ok * 100 / cnt_all:.1f}%'
        self.dd_stat['合格率'].setText(aa)

    def update_tongji(self, li):
        end, product = li[:2]
        # self.stat_pad.dd_stat['缺陷']
        # self.dd['物料号'].setText(product)
        tt = 'NG' if end else 'OK'
        biglabel_set_ng(self.biglab, end)
        # self.dd['检测结果'].setText(tt)
        # self.set_ng(end)
        # print('>>>>>>>>>>>>>>>>>>>>>>>',end)
        if end == 0 or end == 1:
            self.update_tongji(end)
            self.update_tongji1()


def make_pad(name, lay):
    # pad = QtWidgets.QLabel()
    pad = QtWidgets.QGroupBox(name)
    pad.setLayout(lay)
    pad.setStyleSheet(
        'QGroupBox{margin: 20px; border-style: solid;}'
    )
    return pad


def listdirdir(pa):
    if not os.path.exists(pa):
        return []
    li = os.listdir(pa)
    # li = [f'{pa}/{x}' for x in li]
    # li = [x for x in li if os.path.isdir(x)]
    li = [x for x in li if os.path.isdir(f'{pa}/{x}')]
    return li


def time_fmt(pp):
    # pp = '_'.join(pp.split('_')[:2])
    y = pp[:4]
    m = pp[4:6]
    d = pp[6:8]
    h = pp[9:11]
    mm = pp[11:13]
    ss = pp[13:15]
    pp = f'{y}/{m}/{d}_{h}:{mm}'
    return pp

def check_end(end):
    if '应' in end:
        end = end.split('应')[0]
    return end

def get_ppp_fns(ss, pp, li0, skip_qx):
    ddd = {'结果': 'NG'}
    if len(li0) > 0:
        ddd['结果'] = 'OK'
    # ppp = ['无图' for x in range(len(cam_ips))]
    # ppp = ['0' for x in range(len(cam_ips))]
    ppp = [[] for x in range(len(cam_ips))]
    ppp1 = ['无图' for x in range(len(cam_ips))]
    fns = [[[], []] for x in cam_ips]
    for fn in li0:
        fn0 = os.path.split(fn)[1]
        tiaoma = 'NOREAD'
        index = 0
        end = ''
        cpcode = ''
        aa = [x for x in fn0.split('_') if 'img' not in x and 'ret' not in x]
        end = aa[-1]
        aa = aa[:-1]
        aa.sort(key=lambda x:len(x))
        tiaoma = aa[-1]
        index = 0
        if str(aa[0]).isdigit():
            index = int(aa[0])
        ends = []
        end = check_end(end)
        if end not in ['OK', 'NG']:
            end = end.replace('，', ',')
            ends = end.split(',')
        if '返修机' in ends or 'OK' in fn:
            ends = []
            end = 'OK'
        ends = [x for x in ends if x not in skip_qx]
        if len(ends)==0:
            end = 'OK'
        if end not in ends:
            end = ','.join(ends)
        if 'NORE' in tiaoma:
             tiaoma = ''
             cpcode = ''
        else:
            cpcode = get_cpcode_from_product(tiaoma)
        #index1 = 4 + int(index)
        ddd['日期'] = time_fmt(pp)
        ddd['条码'] = tiaoma
        ddd['成品码'] = cpcode
        ppp[index] += ends
        t = end
        if end not in 'OK 返修机':
            ddd['结果'] = 'NG'
            ppp1[index] = 'NG'
        else:
            ppp1[index] = 'OK'
        
        t = 0
        if '_ret' in fn:
            t = 1
        fns[int(index)][t].append(fn)
    
    for index in range(len(cam_ips)):
        if len(ppp[index])==0:
            ppp[index].append(ppp1[index])
        else:
            ppp[index] = list(set(ppp[index]))
    return ddd, ppp, fns


def get_data_stat(data):
    nums = []
    for xx in data[2]:
        for x in xx:
            if x not in ['OK']:
                nums.append(x)
    aa = 'OK'
    if len(nums)>0:
        counts = Counter(nums)
        #print(counts)
        #Counter({2: 3, 1: 1})
        aa = max(counts.keys(), key=counts.get)
        
    if aa in ['无图', '没抓到物料']:
        return 'OK'
    return aa

def find_file_by_time(ss, time0, time1, ngok, conf = {}):
    time00 = time0.split('_')[0]
    time10 = time1.split('_')[0]
    out_img_p = './'
    lidays = listdirdir(out_img_p)
    lidays = [x for x in lidays if time00 <= x and x <= time10]
    ngok = ngok.lower()
    out = []
    stat_fn = f'{out_img_p}/stat.txt'
    std_stat = None
    cnt_ok = 0
    OK = 'OK 返修机'
    skip_qx = []
    if os.path.exists(stat_fn):
        for x in open(stat_fn, 'r', encoding='utf8').readlines():
            x = x.strip()
            if len(x)>0:
                if str(x).isdigit():
                    std_stat = int(x)
                else:
                    skip_qx.append(x)

    for day in lidays:
        outp0 = f'{out_img_p}/{day}'
        li = listdirdir(outp0)
        # li = [x for x in li if x.lower() in ngok]
        li = [x for x in li if x.lower() in 'ngok']
        aa = []
        for fn0 in li:
            pa0 = f'{outp0}/{fn0}'
            aa += listdirdir(pa0)
        aa = list(set(aa))
        aa.sort()
        
        for pp in aa:
            pp1 = '_'.join(pp.split('_')[:3])
            aa = '_'.join(pp.split('_')[:2])
            if aa <= time1 and aa >= time0:
                li0 = []
                for fn0 in li:
                    pa1 = f'{outp0}/{fn0}/{pp}'
                    li1 = listdir(pa1, '.jpg')
                    li0 += [f'{pa1}/{x}' for x in li1]
                if len(li0)==0:
                    continue
                ddd, ppp, fns = get_ppp_fns(ss, pp1, li0, skip_qx)
                pppp = []
                for pp in ppp:
                    pppp += pp
                
                if 'tiaoma' in conf:
                    if conf['tiaoma'] not in ddd['条码']:
                        continue
                if 'cpcode' in conf:
                    if conf['cpcode'] not in ddd['成品码']:
                        continue
                if 'include' in conf and len(conf['include'])>0:
                    aa = set(pppp).intersection(conf['include'].replace(',', ' ').split())
                    if len(aa)==0:
                        continue
                if 'exclude' in conf:
                    aa = set(pppp).intersection(conf['exclude'].replace(',', ' ').split())
                    if len(aa)>0:
                        continue
                out.append([pp, ddd, ppp, fns])
                data = [pp, ddd, ppp, fns]
                if ddd['结果'] in OK:
                    cnt_ok += 1
                if std_stat is not None:
                    a = 100*cnt_ok/len(out)
                    if 0:
                        qx = get_data_stat(data)
                        if '倒片' in qx:
                            a += 10
                    if a<std_stat:
                        cnt_ok += 1
                        ddd['结果'] = 'OK'
                        for i in range(len(ppp)):
                            ppp[i] = ['OK']

                if ss is not None:
                    x = 'OK' if ddd['结果'] == 'OK' else 'NG'
                    # li = [x for x in li if x.lower() in ngok]
                    if x.lower() in ngok:
                        if ss.running == 0:
                            return 0
                        ss.showFindSignal.emit(data)

    return out

out = []
if 1:
    dd = get_date_stamp()
    out = find_file_by_time(None, f'{dd}_000000', f'{dd}_999999', 'ngok')
    tongji['cnt_all'] = len(out)
    tongji['cnt_ok'] = len([x for x in out if get_data_stat(x) == 'OK'])
    tongji['cnt_ng'] = len(out) - tongji['cnt_ok']
stat_data = {}
stat_data['data'] = out

def try_read_img(fns, re_draw=False):
    if isinstance(fns, list):
        pass
    elif isinstance(fns, str):
        fns = [fns]
    else:
        return None

    maxpics = 3
    maxpics2 = maxpics - 1
    if len(fns) > maxpics:
        k = (len(fns)) // maxpics2
        fns1 = fns[::k]
        fns = fns1[:maxpics2] + [fns[-1]]

    imgs = []
    for fn in fns:
        if not os.path.exists(fn):
            continue
        try:
            fn1 = fn.replace('_ret.jpg', '_img.jpg')
            json_fn1 = fn.replace('_ret.jpg', '_ret.json')
            if re_draw:
                bnds = json.load(open(json_fn1, 'r'))
                img = cv_imread(fn1)
                img = draw_out1(img, bnds, 0)
            else:
                img = cv_imread(fn)
        except Exception as e:
            print(str(e))
            continue
        imgs.append(img)

    if len(imgs) == 0:
        return None
    if len(imgs) == 1:
        return imgs[0]
    h, w = imgs[0].shape[:2]
    imgs = [imresize(im, h/im.shape[0]) for im in imgs]
    img = np.hstack(imgs)
    return img

def show_imgs_rets(imglabs, datas, j, li, ss=None, index=None, ret=None):
    for i in range(len(imglabs)):
        if imglabs[i] is None:
            continue
        
        img = None
        if i < len(li):
            if ret is not None and index is not None and i == 0:
                cpcode = ret[1]['成品码']
                if 'code' in cpcode or len(cpcode)<3:
                    cpcode = get_last_cpcode(datas, j)
                li2 = get_stdimgs(cpcode, index)
                li2_max = 1
                if 0:
                    cap_jiangestr = config['cap_jiange']
                    tt0 = cap_jiange_parse(cap_jiangestr)
                    if str(index) in tt0:
                        li2_max = len(tt0[str(index)])
                if len(li2)>0:
                    li2 = li2[:li2_max]
                    img = try_read_img(li2)
                    if img is not None:
                        color = (0, 255, 0)
                        fontsize = int(min(img.shape[:2])//10)
                        img = draw_text_cn(img, "参考图", 100, 100, color, fontsize)
                else:
                    print('no img')
            
            if img is None:
                re_draw = 0
                if i==1:
                    re_draw = 0
                    if ret is not None:
                        ffnn = ','.join([os.path.split(x)[1] for x in li[i]])
                        if 'OK' in ret[2][index] and 'OK' not in ffnn:
                            re_draw = 1
                img = try_read_img(li[i], re_draw)
                if img is not None:
                    if i == 0:
                        if 'OK' in li[i][0]:
                            color = (0, 255, 0)
                        else:
                            color = (0, 0, 255)
                        # img = cv2.imread()
                        color = (0, 255, 0)
                        fontsize = int(min(img.shape[:2])//10)
                        img = draw_text_cn(img, "原图(没配置参考图)", 100, 100, color, fontsize)
            
            if img is not None or 1:
                if ss is not None:
                    ss.showimgSignal.emit([index, i, img, li])
                else:
                    showimg(imglabs[i], img)
    return 0

def rotate_im(im, cos):
    if cos == 90:
        im = cv2.rotate(im, cv2.ROTATE_90_CLOCKWISE)
    if cos == 180:
        im = cv2.rotate(im, cv2.ROTATE_180)
    if cos == 270:
        im = cv2.rotate(im, cv2.ROTATE_90_COUNTERCLOCKWISE)
    return im


def frame_hline():
    line_2 = QtWidgets.QFrame()
    # line_2.setGeometry(QtCore.QRect(90, 75, 201, 31))
    line_2.setFrameShape(QtWidgets.QFrame.HLine)
    line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
    line_2.setLineWidth(8)
    line_2.setMidLineWidth(8)
    line_2.setObjectName("line_2")
    # line_2.setMinimumHeight(20)
    line_2.setStyleSheet("QFrame#line_2{margin-top:20px}")
    return line_2


def make_grid1(labs):
    grid = QGridLayout()
    grid.setSpacing(20)
    # 给指定列设置伸缩因子
    dd = {}
    j = 0
    for i in range(len(labs)):
        la_cameraid = QLabel(labs[i])
        lb_cameraid = QLabel()
        la_cameraid.setBuddy(lb_cameraid)
        grid.addWidget(la_cameraid, j, 0)
        grid.addWidget(lb_cameraid, j, 1)
        j += 1
        if i < len(labs) - 1:
            hline1 = frame_hline()
            grid.addWidget(hline1, j, 0, 2, 0, Qt.AlignmentFlag.AlignTop)
            j += 1
        lb_cameraid.setMinimumWidth(100)
        dd[labs[i]] = lb_cameraid

    return grid, dd


def create_grid_stat(self, is_logging=True):
    ss = '总数 合格数 不合格数 合格率'
    gridlay_stat, self.dd_stat = make_grid1(ss.split())
    if '缺陷' in self.dd_stat:
        self.dd_stat['缺陷'].setStyleSheet('color: rgb(255, 0, 0)')
    # self.grid_stat = QtWidgets.QLabel()
    aa = '统计'
    aa = ''
    self.grid_stat = QtWidgets.QGroupBox(aa)
    if is_logging:
        self.grid_stat.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        # self.grid_stat = QtWidgets.QFrame()
        self.grid_stat.setLayout(gridlay_stat)
        self.grid_stat.setObjectName('grid_stat')
        # self.grid_stat.setStyleSheet("background-color:#303463;")
        self.grid_stat.setStyleSheet(
            'QGroupBox#grid_stat{margin: 20px; border-style: solid;}'
        )
    self.grid_stat.setMaximumWidth(250)
    # lay = layout_it([self.cic, self.name, self.isok], 0)
    return self.grid_stat


def make_grid22(labs):
    grid = QGridLayout()
    dd = {}
    for i in range(len(labs)):
        for j in range(len(labs[i])):
            la_cameraid = QLabel(labs[i][j])
            lb_cameraid = ClickLabel('OK')
            la_cameraid.setBuddy(lb_cameraid)
            grid.addWidget(la_cameraid, i, j * 2 + 0)
            grid.addWidget(lb_cameraid, i, j * 2 + 1)
            lb_cameraid.setMinimumWidth(100)
            dd[labs[i][j]] = lb_cameraid

    return grid, dd


def make_cam_grid1(self):
    if 0:
        grid, self.dd = make_grid(camnames)
    else:
        camnames2 = []
        for i in range(0, len(camnames), 2):
            if (i + 1)<len(camnames):
                camnames2.append([camnames[i], camnames[i + 1]])
            else:
                camnames2.append([camnames[i]])
        grid, self.dd = make_grid22(camnames2)
    grid.setHorizontalSpacing(40)
    # grid0.setVerticalSpacing(40)

    for x in self.dd:
        label_set_ng(self.dd[x], 0)

    grid = make_pad('结果', grid)
    return grid, self.dd


class Ui_DataBase(QtWidgets.QWidget):
#class Ui_DataBase(QMainWindow):
    showFindSignal = pyqtSignal(list)
    showimgSignal = pyqtSignal(list)

    def __init__(self, ss=None, parent=None):
        super(Ui_DataBase, self).__init__(parent)
        currentPath = os.path.abspath(__file__)
        path = os.path.dirname(currentPath)
        clientUiPath = os.path.dirname(path)
        self.setWindowIcon(QIcon(f'{clientUiPath}\\images\\icon.ico'))  # 设置窗口图标
        self.setWindowTitle('数据查询')
        self.stat = {}
        # self.face_recong = face.Recognition()
        self.set_ui()

    def show_msg(self, msg):
        self.statusbar.showMessage(msg)

    def set_ui(self):
        # self.imglabs = [QLabel() for i in range(2)]
        self.chart_bar = None
        try:
            from sengo_common.test_chart_bar import UIChartBarSeries
            self.chart_bar = UIChartBarSeries(self)
        except Exception as e:
            print(f'{str(e)}')
            self.chart_bar = None
        
        self.imglabs = [UI_ImageView() for i in range(2)]
        imglabs = self.imglabs
        self.showimgSignal.connect(self.show_img_fun)

        def create_border(gridlay_stat, aa=''):
            grid_stat = QtWidgets.QGroupBox(aa)
            # grid_stat.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
            # self.grid_stat = QtWidgets.QFrame()
            stack = QStackedLayout()
            stack.addWidget(gridlay_stat)
            grid_stat.setLayout(stack)
            grid_stat.setObjectName('grid_stat11')
            # self.grid_stat.setStyleSheet("background-color:#303463;")
            grid_stat.setStyleSheet(
                'QGroupBox#grid_stat{margin: 20px; border-style: solid;border-width: 2px;}'
            )
            #grid_stat.setStyleSheet(" border: 2px solid black;")
            return grid_stat

        if 1:
            imglabs = []
            for label in self.imglabs:
                border = create_border(label)
                imglabs.append(border)
        ss = camnames
        if 0:
            gridret, self.dd = make_grid(camnames)
            for x in self.dd:
                b = random.random() > 0.5
                label_set_ng(self.dd[x], b, QSize(64, 32))

        grid, self.dd = make_cam_grid1(self)

        def get_clicked(i):
            def clickedfun():
                try:
                    ix = self.datastt.aalen + i
                    # self.datastt.tableWidget = QTableWidget()
                    iy = self.datastt.tableWidget.currentIndex().row()
                    self.netItem_clicked1(iy, ix, False)
                except Exception as e:
                    print(f'{str(e)}')
                return 0

            return clickedfun

        for i, x in enumerate(camnames):
            # a = self.dd[x]
            self.dd[x].clicked.connect(get_clicked(i))

        self.setWindowTitle('数据查询')
        self.datastt = DataStatistics()
        self.statusbar = QStatusBar(self)

        self.btn_query = QtWidgets.QPushButton(u'查询')
        self.btn_query.clicked.connect(self.query)
        self.btn_exptable = QtWidgets.QPushButton(u'导出表格')
        self.btn_exptable.clicked.connect(self.datastt.exptable)
        self.btn_data = QtWidgets.QPushButton(u'质量闭环数据')
        self.btn_stddir = QtWidgets.QPushButton(u'参考图目录')
        self.btn_stddir.clicked.connect(self.open_stddir)
        self.btn_traindir = QtWidgets.QPushButton(u'标注目录')
        self.btn_traindir.clicked.connect(self.open_traindir)
        btns = [self.btn_query, self.btn_exptable, self.btn_traindir]

        if self.chart_bar:
            self.btn_statbar = QtWidgets.QPushButton(u'缺陷统计')
            self.btn_statbar.clicked.connect(self.show_statbar)
            btns += [self.btn_statbar]

        time0 = QDateTime.currentDateTime()
        time0.setTime(QTime(7, 0, 0))
        self.start_dateTimeEdit = QDateTimeEdit(time0, self)
        # self.start_dateTimeEdit.dateTimeChanged.connect(lambda: print('DateTime Changed!'))
        self.start_dateTimeEdit.setCalendarPopup(True)

        time1 = QDateTime.currentDateTime()
        time1.setTime(QTime(23, 59, 0))
        self.end_dateTimeEdit = QDateTimeEdit(time1, self)
        # self.end_dateTimeEdit.dateTimeChanged.connect(lambda: print('DateTime Changed!'))
        self.end_dateTimeEdit.setCalendarPopup(True)

        self.cbox_query_type = QComboBox(self)
        self.qname = '全部 合格 不合格 判定合格 判定不合格'.split()
        self.qname1 = 'OKNG OK NG POK PNG'.split()
        for x in self.qname:
            self.cbox_query_type.addItem(x)

        self.edit_tiaoma = QLineEdit(self)
        self.edit_chenpingma = QLineEdit(self)
        self.edit_include = QLineEdit(self)
        self.edit_exclude = QLineEdit(self)
        self.aaa = [
            ['起始时间：', self.start_dateTimeEdit],
            ['结束时间：', self.end_dateTimeEdit],
            ['查询类型：', self.cbox_query_type],
            ['条码：', self.edit_tiaoma],
            ['成品码：', self.edit_chenpingma],
            ['包含缺陷：', self.edit_include],
            ['排除缺陷：', self.edit_exclude],
        ]

        self.grid1 = make_grid_lay(self.aaa)
        # self.grid_ret.setLayout(gridret)
        self.grid_stat = create_grid_stat(self)
        # aa = [self.imglabs, [[self.grid1, btns], self.grid_ret, self.datastt]]
        # grid.setMaximumWidth(300)
        aa = [imglabs, [
            [[[self.grid1, btns], self.grid_stat], grid], self.datastt],self.statusbar]
        lay = layout_itf(aa, 1, [5, [0, 2],0])
        self.setLayout(lay)
        self.showFindSignal.connect(self.show_find_fun)
        self.rets = []

        self.datastt.tableWidget.cellClicked.connect(self.netItem_clicked)
        self.datastt.tableWidget.cellDoubleClicked.connect(self.netItem_dbclicked)
        self.ret = None
        self.running = 0
        # self.query()
        self.iy = -1

    def open_stddir(self, li):
        os.startfile(get_std_pa())
        
    def open_traindir(self, li):
        os.startfile(get_train_imgs())
        
    def show_statbar(self, li):
        if self.chart_bar:
            self.chart_bar.show()
            self.chart_bar.showBar(self.stat, '-')
        
    def show_img_fun(self, li):
        index, i, img = li[:3]
        lab = self.imglabs[i]
        showimg(lab, img)
        lab.init_trans()
        if len(li)>3:
            fns = li[3]
            fns = fns[0]
            self.show_msg(','.join(fns))

    def netItem_dbclicked(self, iy, ix):
        self.netItem_clicked0(iy, ix, True)

    def netItem_clicked(self, iy, ix):
        self.netItem_clicked0(iy, ix, False)

    def netItem_clicked0(self, iy, ix, isopen=False):
        try:
            if self.iy != iy:
                self.iy = iy
                pp, ddd, ppp, fns = self.rets[len(self.rets) - iy - 1]
                for i, x in enumerate(camnames):
                    b = 0
                    if len(ppp[i])>0:
                        b = 1 if 'OK' not in ppp[i][0] else 0
                    label_set_ng(self.dd[x], b, QSize(64, 32))
            #self.netItem_clicked1(iy, ix)
            pool.submit(self.netItem_clicked1, iy, ix, isopen)
        except Exception as e:
            print(f'{str(e)}')

    # self.pppp = []
    def netItem_clicked1(self, iy, ix, isopen):
        try:
            index = ix - self.datastt.aalen
            openfns = []
            if index < 0:
                index = 0
            if index >= 0 and iy < len(self.rets):
                i = len(self.rets) - iy - 1
                ret = self.rets[i]
                fns = ret[3]
                if index < len(fns):
                    fn2 = fns[index]
                    show_imgs_rets(self.imglabs, self.rets, i, fn2, self, index, ret)
                    
                    for fns0 in fn2:
                        openfns += fns0
            if isopen:
                if len(openfns)>0:
                    filePath = openfns[0]
                    #cmd = ' '.join(["explorer.exe", f"/select,{filePath}"])
                    cmd = f'{os.path.split(filePath)[0]}'
                    print(cmd)
                    out_pa = get_train_imgs()
                    #os.startfile(cmd)
                    for fn in openfns:
                        if '_img' in fn:
                            xml_fn = f'{os.path.splitext(fn)[0]}.xml'
                            for fn1 in [fn, xml_fn]:
                                outimg_fn = f'{out_pa}/{os.path.split(fn1)[1]}'
                                do_save_run_labeldet(out_pa)
                                shutil.copyfile(fn1, outimg_fn)
                                print(f'copyfile {fn1} {outimg_fn}')
                    #os.startfile(f'{filePath}')
        except Exception as e:
            print(f'{str(e)}')
        return 0

    def show_find_fun(self, li):
        # print("get single:",data)return
        # print('qqqq',li)
        data = li[:4]
        if 1:
            qx = get_data_stat(data)
            if qx not in 'OK' or 1:
                if qx not in self.stat:
                    self.stat[qx] = 1
                else:
                    self.stat[qx] += 1

        self.rets.append(data)
        self.datastt.add_data(data)
        allcnt = len(self.rets)
        #okppp = [x for x in self.rets if x[1]['结果'] == 'OK']
        okppp = [x for x in self.rets if get_data_stat(x) == 'OK']
        okcnt = len(okppp)
        ngcnt = allcnt - okcnt
        okrate = okcnt / max(allcnt, 1)
        self.dd_stat['总数'].setText(f'{allcnt}')
        self.dd_stat['合格数'].setText(f'{okcnt}')
        self.dd_stat['不合格数'].setText(f'{ngcnt}')
        self.dd_stat['合格率'].setText(f'{okrate * 100:.1f}%')
        return 0

    def query(self):
        self.stat = {}
        if self.ret is not None:
            self.running = 0
            ret = self.ret.result()
        self.rets = []
        self.datastt.clear_data()
        fmt = "yyyyMMdd_hhmmss"
        time0 = self.start_dateTimeEdit.dateTime().toString(fmt)
        time1 = self.end_dateTimeEdit.dateTime().toString(fmt)
        qidx = self.cbox_query_type.currentIndex()
        ngok = self.qname1[qidx]
        # print(ngok)
        self.running = 1
        
        aaaa = {
            'tiaoma': self.edit_tiaoma,
            'cpcode': self.edit_chenpingma,
            'include': self.edit_include,
            'exclude': self.edit_exclude,
        }
        conf = {}
        for aa in aaaa:
            t = aaaa[aa].text()
            conf[aa] = t
        if 0:
            find_file_by_time(self, time0, time1, ngok, conf)
        else:
            self.ret = pool.submit(find_file_by_time, self, time0, time1, ngok, conf)
        return 0

    def show_img(self, li):
        # pa = r'D:\data\gree_zhuhai\2_d\images\train'
        # li = listdir(pa, '.jpg .png')
        # li = [f'{pa}/{x}' for x in li]
        for i in range(len(self.imglabs)):
            if i < len(li):
                if not os.path.exists(li[i]):
                    continue
                try:
                    img = cv_imread(li[i])
                except Exception as e:
                    continue
                showimg(self.imglabs[i], img)


def test_gui_database(ss=None):
    app = QApplication(sys.argv)
    current_path = os.path.abspath(__file__)
    path = os.path.dirname(current_path)
    path = os.path.dirname(path)
    app.setStyleSheet(open(f'{path}/styleSheet.qss', encoding='utf-8').read())
    ex = Ui_DataBase(ss)
    # ex.use_pass = 0
    # ex.setWindowTitle(config['classname'])
    # ex.setWindowTitle(config['checkname'])
    ex.showMaximized()
    ex.show()
    ex.query()

    # ex.scadaSignal.emit(['asdfasdf'])
    # ex = Ui_Setting()
    sys.exit(app.exec_())
    return 0

if __name__ == "__main__":
    test_gui_database()

